package com.example.mq.mqServer.dao;

import com.example.mq.Application;
import com.example.mq.mqServer.core.Binding;
import com.example.mq.mqServer.core.MSGQueue;
import com.example.mq.mqServer.core.exchange.Exchange;
import com.example.mq.mqServer.core.exchange.ExchangeType;
import com.example.mq.mqServer.exception.MqException;
import com.example.mq.mqServer.mapper.MetaMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;

import java.io.File;
import java.util.List;

/**
 * @BelongsProject: 0.mq
 * @BelongsPackage: com.example.mq.mqServer.dao
 * @Author : 游在海里的鱼
 * @CreateTime : 2023-12-09  23:00
 * @Version : 1.0
 * @CLassName : SQLite管理者
 * @Description : 管理和调用SQLite的Mapper
 */
@Slf4j
public class DataBaseManager {

    //数据库的映射
    private MetaMapper metaMapper;


    /** ---------------------------------------------------------------------------------------------------------------------
    * @Method  : 对象初始化
    * @Describe: 获取Mapper的Bean，创建目录“data“，在SQLite中建立MQ的默认库表
    * @modifier: [public] [实例方法]
    **/
    public void init()  {
        //Application.context = SpringApplication.run(Application.class);
        //1.从Spring框架里取出Mapper的Bean
        metaMapper = Application.context.getBean(MetaMapper.class);
        //2.创建目录“data”
        File data = new File("./data");
        if(!data.exists()){
            data.mkdirs();
        }
        //3.在SQLite中建立MQ的默认库表（在SQLite中meta.db就等价于库）
        //库文件存在，则跳过初始化
        if(new File("./data/meta.db").exists()){
            new MqException("[DataBaseManager] [init] [meta.db]已存在").printStackTrace();
        }else {
        //库不存在，则建库建表
            //在建表的时候，会自动在目录"data"下创建“meta.db”这个文件
            metaMapper.createExchangeTable();
            metaMapper.createQueueTable();
            metaMapper.createBindingTable();
        //4.RabbitMQ有个设定：设置一个匿名的交换机，类型为DIRECT
            metaMapper.insertExchange(new Exchange("", ExchangeType.DIRECT,true));
        }
        log.info("[init] [SQLite管理者]初始化完成");
    }


    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 删除SQLite的库表
     * @Describe: 就是删除SQLite的数据库文件"meta.db"
     * @modifier: [public] [实例方法]
    **/
    public boolean deleteDataBase(){
        //1.因为context里持有了一个MetaMapper的Bean，而这个Bean打开了文件”meta.db“,被打开的文件无法删除
        Application.context.close( );

        //2.删除库（文件）成功
        if(new File("./data/meta.db").delete()){
            log.info("[deleteDataBase] [meta.db]删除成功");
            return true;
        //3.删除库（文件）失败
        }else {
            new MqException("[DataBaseManager] [删除库] [meta.db]删除失败").printStackTrace();
        }
        return false;
    }


    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 交换机的Mapper
     * @Describe: 增,删,查全部,查单个
     * @modifier: [public] [实例方法]
    **/
    public void insertExchange(Exchange exchange){
        metaMapper.insertExchange(exchange);
        log.debug("[新增交换机] [交换机:"+exchange.getName()+"]往[数据库meta.db]插入成功");
    }
    public void deleteExchange(String exchangeName) {
        metaMapper.deleteExchange(exchangeName);
        log.debug("[删除交换机] [交换机:"+exchangeName+"]从[数据库meta.db]删除成功");
    }
    public List<Exchange> selectAllExchange(){
        List<Exchange> ret = metaMapper.selectAllExchange();
        log.debug("[查询所有交换机] [全部交换机]从[数据库meta.db]查询成功");
        return ret;
    }
    public Exchange selectOneExchange(String exchangeName){
        Exchange ret = metaMapper.selectOneExchange(exchangeName);
        log.debug("[查询单个交换机] [交换机:"+exchangeName+"]从[数据库meta.db]查询成功");
        return ret;
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 队列的Mapper
     * @Describe: 增,删,查所有
     * @modifier: [public] [实例方法]
    **/
    public void insertQueue(MSGQueue queue){
        metaMapper.insertQueue(queue);
        log.debug("[新增队列] [队列:"+queue.getName()+"]往[数据库meta.db]插入成功");
    }
    public void deleteQueue(String queueName) {
        metaMapper.deleteQueue(queueName);
        log.debug("[删除队列] [队列:"+queueName+"]从[数据库meta.db]删除成功");
    }
    public List<MSGQueue> selectAllQueue(){
        List<MSGQueue> ret = metaMapper.selectAllQueue();
        log.debug("[查询所有队列] [全部队列]从[数据库meta.db]查询成功");
        return ret;
    }

    /** ---------------------------------------------------------------------------------------------------------------------
     * @Method  : 绑定的Mapper
     * @Describe: 增,删,查所有,查单个
     * @modifier: [public] [实例方法]
    **/
    public void insertBinding(Binding binding){
        metaMapper.insertBinding(binding);
        log.debug("[新增绑定] ["+binding.getQueueName()+"]绑定["+binding.getExchangeName()+"]到[数据库meta.db]里");
    }
    public void deleteBinding(Binding binding) {
        metaMapper.deleteBinding(binding);
        log.debug("[删除绑定] ["+binding.getQueueName()+"]解绑["+binding.getExchangeName()+"]从[数据库meta.db]里");

    }
    public List<Binding> selectAllBinding(){
        List<Binding> ret = metaMapper.selectAllBinding();
        log.debug("[查询所有绑定] [全部绑定]从[数据库meta.db]查询成功");
        return ret;
    }
    public Binding selectOneBinding(Binding binding){
        Binding ret = metaMapper.selectOneBinding(binding);
        log.debug("[查询单个绑定] ["+binding.getQueueName()+"]和["+binding.getExchangeName()+"]的绑定从[数据库meta.db]查询成功");
        return ret;
    }

}
